package com.yumeng.common.runtime;

import com.yumeng.common.api.ApiCode;
import lombok.extern.slf4j.Slf4j;

/**
 * 声明为static是让ThreadLocal实例随着程序的结束才结束，这样才不会让GC回收了
 * 声明为final是让ThreadLocal实例引用不会被替换，这样子也不会因为被替换导致被GC回收
 * 这两个声明都是为了避免作为key的ThreadLocal对象没有外部强引用而导致被GC回收，从而导致内存泄漏的问题
 * 因为ThreadLocalMap<ThreadLocal, Object>中的ThreadLocal对象作为key是弱引用，会被GC回收
 *
 * //TODO 很久之前写的，现在都不怎么确定了
 * @author wxd
 * @date 2022/5/25 17:02
 */
@Slf4j
public class ThreadLocalHelper {

    /**
     * 保存返回结果的特殊code值
     */
    private static final ThreadLocal<ApiCode> apiCodeThreadLocal = new ThreadLocal<>();
    public static ApiCode getApiCode(){
        ApiCode val = apiCodeThreadLocal.get();
        if (val != null){
            apiCodeThreadLocal.remove();
        }
        return val;
    }
    public static void setApiCode(ApiCode apiCode){
        apiCodeThreadLocal.set(apiCode);
    }


    /**
     * 检查ThreadLocalHelper是否及时清理
     */
    public static void checkThreadLocalHelper(){
        Object val = apiCodeThreadLocal.get();
        if (val != null){
            log.warn("ThreadLocalHelper未清理:apiCodeThreadLocal:{}", val);
            apiCodeThreadLocal.remove();
        }
    }


/*    public static void main(String[] args) {


    }*/

    /*private static ExecutorService executorService = Executors.newCachedThreadPool();
    private static void testThreadLocal(){
        ThreadLocal<Boolean> threadLocal = new ThreadLocal<>();
        threadLocal.set(Boolean.TRUE);
        executorService.execute(() -> {
            //threadLocal.set(Boolean.FALSE);
            System.out.println("子线程设置为：" + threadLocal.get());
        });
        System.out.println("主线程设置为：" + threadLocal.get());
        executorService.shutdown();
    }
    private static void testInheritableThreadLocal(){
        InheritableThreadLocal<Boolean> threadLocal = new InheritableThreadLocal<>();

        threadLocal.set(Boolean.TRUE);

        executorService.execute(() -> {
            System.out.println("子线程获取到主线程设置的值：" + threadLocal.get());
        });

        executorService.shutdown();
    }

    private static ExecutorService fixedService = Executors.newFixedThreadPool(1);
    private static void testInheritableThreadLocal2(){
        InheritableThreadLocal<Integer> threadLocal = new InheritableThreadLocal<>();

        threadLocal.set(1);
        threadLocal.set(2);

        fixedService.execute(() -> {
            System.out.println("子线程 1 获取到主线程设置的值：" + threadLocal.get());
        });
        threadLocal.set(3);
        fixedService.execute(() -> {
            System.out.println("子线程 2 获取到主线程设置的值：" + threadLocal.get());
        });

        fixedService.shutdown();
    }*/
}
